package implementation1.app.commands;

import exceptions.CommandErrorFromUserException;
import exceptions.CommandException;
import exceptions.StreamException;
import implementation1.app.Global;
import implementation1.app.streams.AccessAttributes;
import implementation1.data.states.TerminatedStatus;
import interfaces.app.IProcess;
import interfaces.data.IHandle;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Class for handle command "man" for showing help.
 * Created: 22.10.11
 *
 * @author Jan Svab
 */
public class Man extends Command
{
    private final String PATH_TO_HELP_DIR = "implementation1/res/help/";

    /**
     * Default constructor.
     *
     * @param parent parent process over which is command processed
     * @param handle parameters of command
     */
    public Man(IProcess parent, IHandle handle)
    {
        super(parent, handle);
    }

    /**
     * Main method for processing of command.
     *
     * @param args arguments of command
     * @throws CommandException Thrown if occurs error during processing of the command
     */
    @Override
    public void mainCommand(String[] args) throws CommandException
    {
        String manForCommand = "";
        if (args == null || args.length == 0)
        {
            manForCommand = "";   //will be load '.man'
        }
        else if (args.length == 1)
        {
            manForCommand = args[0];
        }
        else
        {
            throw new CommandErrorFromUserException(bundle.getString("error.arguments.wrongCount"));
        }

        List<String> buffer = new ArrayList<String>();
        InputStream inputSt = null;
        BufferedReader bfReader = null;

        inputSt = getClass().getClassLoader().getResourceAsStream(PATH_TO_HELP_DIR + manForCommand + ".man");

        if (inputSt == null)
        {
            throw new CommandErrorFromUserException(
                    bundle.getString("error.man.missingBefore") + manForCommand + bundle.getString("error.man.missingAfter"));
        }

        bfReader = new BufferedReader(new InputStreamReader(inputSt));

        try
        {
            while (bfReader.ready())
            {
                String line = bfReader.readLine();

                if (hasEndStatus())
                {
                    break;
                }

                if (Thread.interrupted())
                {
                    status = new TerminatedStatus();
                }

                buffer.add(line);
            }

        } catch (Exception e)
        {
            throw new CommandException(bundle.getString("error.man.readHelpError"));
        } finally
        {
            //standard closing of stream with help
            try
            {
                if (bfReader != null) bfReader.close();
                if (inputSt != null) inputSt.close();
            } catch (IOException e1)
            {
                throw new CommandException(e1.getMessage());
            }
        }

        try
        {
            handle.getOut().open(AccessAttributes.WRITE);
            openedStreamsOfProcess.add(handle.getOut());

            for (String ln : buffer)
            {
                handle.getOut().writeLine(ln);

                if (hasEndStatus())
                {
                    break;
                }

                if (Thread.interrupted())
                {
                    status = new TerminatedStatus();
                }
            }

        } catch (StreamException e)
        {
            throw new CommandException(e.getMessage());
        } finally
        {
            Global.closeStreamQuietly(handle.getOut());
            openedStreamsOfProcess.remove(handle.getOut());
        }
    }

    @Override
    public String toString()
    {
        return "man";
    }
}
